package com.zwr.sheller.shop.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zwr.sheller.core.util.JsonUtil;
import com.zwr.sheller.shop.mapper.SalesDataMapper;
import com.zwr.sheller.shop.service.SalesDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.Date;
import java.util.*;

/**
 * @author 付龙江
 * @date 2022/1/7 17:13
 */
@Service("salesDataService")
@Transactional(rollbackFor = Throwable.class)
public class SalesDataServiceImpl implements SalesDataService {
    private final static String REMARK_ID = "remark:";
    private final static Long STORE_ID=1L;
    SalesDataMapper salesDataMapper;
    RedisTemplate<String, Object> template;
    ValueOperations<String, Object> stringOps;
    @Autowired(required = false)
    public SalesDataServiceImpl(SalesDataMapper salesDataMapper, RedisTemplate<String, Object> template) {
        this.salesDataMapper = salesDataMapper;
        this.template = template;
        stringOps = template.opsForValue();
        //Long storeId = GetThreadLocal.getStoreId();
    }


    /**
     * 销售统计
     * @param from 开始时间
     * @param to 截止时间
     * @param page 页码
     * @param size 每页条数
     * @return 销售统计数据
     */
    @Override
    public Map<String, Object> selectSalesData(String from, String to, Integer page, Integer size) {
        //分页操作：对查询所有订单进行分页
        PageHelper.startPage(page,size);
        List<Map<String, Object>> list1 = salesDataMapper.selectSalesData(from, to, STORE_ID);
        PageInfo<Map<String, Object>> of1 = PageInfo.of(list1);
        List<Map<String, Object>> newList1 = of1.getList();
        //每天成功了的订单不用分页（数量不多可以用双层嵌套循环）
        List<Map<String, Object>> list2 = salesDataMapper.selectSuccessSales(from, to, STORE_ID);
        //对应时间上进行拼接
        for (Map<String, Object> map : newList1) {
            for (Map<String, Object> map2 : list2) {
                //如果有相等的就进行拼接
                if (map.get("dayTime").equals(map2.get("dayTime"))){
                    map.put("successOrder",map2.get("successOrder"));
                    map.put("totalMoney",map2.get("totalMoney"));
                }
            }
            //结束了都没相等的就重新赋值
            if (StringUtils.isEmpty(map.get("successOrder"))){
                map.put("successOrder",0);
            }
            if (StringUtils.isEmpty(map.get("totalMoney"))){
                map.put("totalMoney",0);
            }
        }
        //去除总计  再拼接到一个新的map上
        Map<String,Object> data = new HashMap<>(16);
        data.put("salesCount",newList1);
        data.put("total",of1.getTotal());
        return data;
    }

    /**
     * @return 导出销售统计列表
     */
    @Override
    public List<Map<String,Object>> uploadSalesData(String from, String to) {

        List<Map<String, Object>> list1 = salesDataMapper.selectSalesData(from, to, STORE_ID);
        //每天成功了的订单不用分页（数量不多可以用双层嵌套循环）
        List<Map<String, Object>> list2 = salesDataMapper.selectSuccessSales(from, to, STORE_ID);
        //对应时间上进行拼接
        for (Map<String, Object> map : list1) {
            for (Map<String, Object> map2 : list2) {
                //如果有相等的就进行拼接
                if (map.get("dayTime").equals(map2.get("dayTime"))){
                    map.put("successOrder",map2.get("successOrder"));
                    map.put("totalMoney",map2.get("totalMoney"));
                }
            }
            //结束了都没相等的就重新赋值
            if (StringUtils.isEmpty(map.get("successOrder"))){
                map.put("successOrder",0);
            }
            if (StringUtils.isEmpty(map.get("totalMoney"))){
                map.put("totalMoney",0);
            }
        }
        return list1;
    }

    /**
     * @return 订单统计是数据
     */
    @Override
    public Map<String, Object> selectOrderCount() {
        //创建一个map容器用于装顶所有数据
        Map<String,Object> map = new HashMap<>(16);
        //今日成交订单数
        map.put("todayOrders",salesDataMapper.selectTodayOrder(STORE_ID));
        //昨日成交订单数
        map.put("yesterdayOrders",salesDataMapper.selectYesterdayOrder(STORE_ID));
        //7日成交订单数
        map.put("sevenDaysOrders",salesDataMapper.selectSevenDaysOrder(STORE_ID));
        //近一个月成交订单数
        map.put("lastMonthOrders",salesDataMapper.selectLastMonth(STORE_ID));
        //近7天订单走势图（有可能有一天没有订单数据，查到的条数就不够7天，为保证传过去的是7天，需要数据校验）
        List<Map<String, Object>> sevenList = salesDataMapper.selectSevenDayImg(STORE_ID);
        List<Map<String, Object>> newSevenList = new ArrayList<>();
        //获取最近七天日期
        List<String> lastSevenDayList = lastDays(7);
        if (sevenList==null){
            for (String s : lastSevenDayList) {
                Map<String, Object> dayMap = new HashMap<>(16);
                dayMap.put("dayTime",s);
                dayMap.put("count",0);
                newSevenList.add(dayMap);
            }
        }else {
            a1:for (String day : lastSevenDayList) {
                for (Map<String, Object> stringDay : sevenList) {
                    if (day.equals(stringDay.get("dayTime").toString())){
                        //为了保证顺序存到一个新的list中
                        newSevenList.add(stringDay);
                        //找到相同的，就回到上一个循环开始的位置
                        continue a1;
                    }
                }
                //没有相同的，该日期就赋值为0
                Map<String, Object> dayMap = new HashMap<>(16);
                dayMap.put("dayTime",day);
                dayMap.put("count",0);
                newSevenList.add(dayMap);
            }
        }
        map.put("sevenList",newSevenList);
        //近15天数据
        List<Map<String, Object>> halfOfMonthList = salesDataMapper.selectHalfOfMonthImg(STORE_ID);
        List<Map<String, Object>> newHalfOfMonthList = new ArrayList<>();
        System.out.println(halfOfMonthList);
        //获取半个月日期
        List<String> fifteenList = lastDays(15);
        //为null都为0
        if (halfOfMonthList==null){
            for (String s : fifteenList) {
                Map<String, Object> dayMap = new HashMap<>(16);
                dayMap.put("dayTime",s);
                dayMap.put("count",0);
                newHalfOfMonthList.add(dayMap);
            }
        }else {
            a1:for (String day : fifteenList) {
                for (Map<String, Object> stringDay : halfOfMonthList) {
                    if (day.equals(stringDay.get("dayTime").toString())){
                        newHalfOfMonthList.add(stringDay);
                        //找到相同的，就回到上一个循环开始的位置
                        continue a1;
                    }
                }
                //没有相同的，该日期就赋值为0
                Map<String, Object> dayMap = new HashMap<>(16);
                dayMap.put("dayTime",day);
                dayMap.put("count",0);
                newHalfOfMonthList.add(dayMap);
            }
        }
        map.put("halfOfMonthList",newHalfOfMonthList);
        return map;
    }


    /**
     * 获取指定几天的年月日
     * @param day 要拿到几天
     * @return 返回时间集合
     */
    private List<String> lastDays(Integer day){
        //获取当前时间毫秒值
        long now = System.currentTimeMillis();
        List<String> timeString = new ArrayList<>();
        for (int i = 0; i < day; i++) {
            //转换成年月日形式的字符串
            timeString.add(new Date(now).toString());
            //上一天（下一天用+=）
            now-=86400000;
        }
        return timeString;
    }

    /**
     * @param from 开始时间
     * @param to 结束时间
     * @return 订单统计下的具体订单信息
     */
    @Override
    public PageInfo<Map<String, Object>> selectSpecificOrder(String from, String to, Integer page, Integer size) {
        PageHelper.startPage(page,size);
        List<Map<String, Object>> list = salesDataMapper.selectSpecificOrder(from, to, STORE_ID);
        for (Map<String, Object> map : list) {
            //修改时间格式
            if (map.get("createTime")!=null){
                map.put("createTime",map.get("createTime").toString().substring(0,19));
            }
        }
        return PageInfo.of(list);
    }

    /**
     * @param from 开始时间
     * @param to 结束时间
     * @return 返回导出数据
     */
    @Override
    public List<Map<String, Object>> uploadSpecificOrder(String from, String to) {
        List<Map<String, Object>> list = salesDataMapper.selectSpecificOrder(from, to, STORE_ID);
        for (Map<String, Object> map : list) {
            //修改时间格式
            if (map.get("createTime")!=null){
                map.put("createTime",map.get("createTime").toString().substring(0,19));
            }
        }
        return list;
    }

    /**
     * 销售明细
     *
     * @param from               开始时间
     * @param to                 结束时间
     * @param page               页码
     * @param size               每页条数
     * @param notPayStatus       待付款
     * @param deliverGoodsStatus 待发货
     * @param getGoodsStatus     待收货
     * @param backGoodsStatus    退货
     * @param cancelStatus       已取消
     * @param successStatus      已完成
     * @param usToOrderStatus    自提订单
     * @return 返回符合以上要求的数据
     */
    @Override
    public PageInfo<Map<String, Object>> selectSalesDetail(String from, String to, Integer page,
                                                       Integer size, Integer notPayStatus,
                                                       Integer deliverGoodsStatus, Integer getGoodsStatus,
                                                       Integer backGoodsStatus, Integer cancelStatus,
                                                       Integer successStatus, Integer usToOrderStatus) {
        //开启分页
        PageHelper.startPage(page,size);
        //拿到要分页的数据
        List<Map<String, Object>> list = salesDataMapper.selectSalesDetail(from,to,STORE_ID,notPayStatus,
                deliverGoodsStatus,getGoodsStatus,backGoodsStatus,cancelStatus,successStatus,usToOrderStatus);
        for (Map<String, Object> map : list) {
            //修改时间格式
            if (map.get("createTime")!=null){
                map.put("createTime",map.get("createTime").toString().substring(0,19));
            }
        }
        return PageInfo.of(list);
    }

    /**
     * 导出销售明细
     *
     * @param from               开始时间
     * @param to                 结束时间
     * @param notPayStatus       待付款
     * @param deliverGoodsStatus 待发货
     * @param getGoodsStatus     待收货
     * @param backGoodsStatus    退货
     * @param cancelStatus       已取消
     * @param successStatus      已完成
     * @param usToOrderStatus    自提订单
     * @return 返回符合以上要求的数据
     */
    @Override
    public List<Map<String, Object>> uploadSalesDetail(String from, String to, Integer notPayStatus, Integer deliverGoodsStatus, Integer getGoodsStatus, Integer backGoodsStatus, Integer cancelStatus, Integer successStatus, Integer usToOrderStatus) {
        List<Map<String, Object>> list = salesDataMapper.selectSalesDetail(from, to, STORE_ID, notPayStatus,
                deliverGoodsStatus, getGoodsStatus, backGoodsStatus, cancelStatus, successStatus, usToOrderStatus);
        for (Map<String, Object> map : list) {
            //修改时间格式
            if (map.get("createTime")!=null){
                map.put("createTime",map.get("createTime").toString().substring(0,19));
            }
        }
        return list;
    }

    /**
     * 销售排行
     *
     * @param from   开始时间
     * @param to     截止时间
     * @param page   页码
     * @param size   每页条数
     * @param status 状态
     * @return 返回要求数据
     */
    @Override
    public PageInfo<Map<String, Object>> selectSalesRanking(String from, String to, Integer page, Integer size, Integer status) {
        PageHelper.startPage(page,size);
        List<Map<String, Object>> list = salesDataMapper.selectSalesRanking(from, to, STORE_ID, status);
        return PageInfo.of(list);
    }

    /**
     * 导出销售排行
     *
     * @param from   开始时间
     * @param to     截止时间
     * @param status 状态
     */
    @Override
    public List<Map<String, Object>> uploadSalesRanking(String from, String to, Integer status) {
        //拿到要导出的信息
        List<Map<String, Object>> list = salesDataMapper.selectSalesRanking(from, to, STORE_ID, status);
        //拿到排行的长度
        int listSize = list.size();
        //对要导出的信息添加排行
        if (status == null || status == 1 || status == 3){
            for (int i = 0; i < list.size(); i++) {
                list.get(i).put("rank",i+1);
            }
        }else {
            for (int i = 0; i < list.size(); i++) {
                list.get(i).put("rank",listSize--);
            }
        }
        return list;
    }

    /**
     * 首页信息
     *
     * @return 商铺、商品、订单、订单走势图、交易排名
     */
    @Override
    public Map<String, Object> selectIndexMessage() {

        //拿到店铺信息
        Map<String, Object> storeMap = salesDataMapper.selectStoreMessage(STORE_ID);
        //拿到该商铺所有编号
        List<Long> goodsIds = salesDataMapper.selectGoodsIds(STORE_ID);
        if (goodsIds==null||goodsIds.size()<1){
            //当店铺没有商铺时，商铺的评分为0
            storeMap.put("score","暂无评分");
        }else {
            //计数器
            long count = 0L;
            //求和
            long sum = 0L;
            for (Long goodsId : goodsIds) {
                //拿到以下要求的所有key
                Set<String> keys = template.keys(REMARK_ID + goodsId + ":*");
                //存在该评论的时候才进行取值
                if (keys!=null||keys.size()>=1){
                    //循环取值
                    for (String key : keys) {
                        Object o = stringOps.get(key);
                        Map map = JsonUtil.stringToObject(String.valueOf(o), Map.class);
                        count++;
                        System.out.println(map.get("rank"));
                        sum += Long.parseLong(map.get("rank").toString());
                    }
                }
            }
            if (count<=0L){
                //如果所有商品都没有评分
                storeMap.put("score","暂无评分");
            }else {
                //有评分(取平均分)
                storeMap.put("score",sum/count);
            }
        }
        Map<String, Object> map = new HashMap<>(16);
        map.put("storeMessage",storeMap);
        //待付款
        map.put("notPay", salesDataMapper.selectNotPay(STORE_ID));
        //待发货
        map.put("notSendGoods", salesDataMapper.selectNotSendGoods(STORE_ID));
        //待收货
        map.put("notGetGoods", salesDataMapper.selectNotGetGoods(STORE_ID));
        //维权订单
        map.put("backGoods", salesDataMapper.selectBackGoods(STORE_ID));
        //自提订单
        map.put("usToOrder", salesDataMapper.selectUsToOrder(STORE_ID));
        //出售中的商品
        map.put("salesGoods", salesDataMapper.selectSalesGoods(STORE_ID));
        //今日上架
        map.put("todayUpGoods", salesDataMapper.selectTodayUpGoods(STORE_ID));
        //下架商品
        map.put("downGoods", salesDataMapper.selectDownGoods(STORE_ID));
        //库存预警
        map.put("stockWarning", salesDataMapper.selectStockWarning(STORE_ID));
        //仓库商品
        map.put("stockGoods", salesDataMapper.selectStockGoods(STORE_ID));
        //7日和15日订单
        Map<String, Object> orderCount = selectOrderCount();
        map.put("sevenList", orderCount.get("sevenList"));
        map.put("halfOfMonthList", orderCount.get("halfOfMonthList"));
        //按交易量排名前十
        PageInfo<Map<String, Object>> mapPageInfo = selectSalesRanking(null, null, 1, 10, 1);
        map.put("top10Sales",mapPageInfo.getList());
        return map;
    }
}
